package com.blahti.example.drag2;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.util.Vector;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import com.icons.draw.view.LocationViewers;

import data.Coordinate;
import data.ParkingDB;
import data.ParkingSpot;
import data.ParkingSpotsList;
import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.preference.PreferenceManager;
import android.widget.Toast;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.util.Log;

public class RefreshService extends Service {
	private NotificationManager notificationMgr;
	private boolean runningFlag = false;
	int counter=0;
	ParkingDB parking_db;
	//public Vector<ParkingSpotsList> parkingVector=null;
	String RspType="";
	Double latitude;
	Double longitude;
	DrawIcons di;
	public static final String TAG = "Refresh Service";


	
	private final Handler handler = new Handler() {  

		public void handleMessage(Message msg) {
			String result = msg.getData().getString("RESPONSE"); 
			String Reason="";
			Log.d("response from server",result);
			try {
				
				DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
				DocumentBuilder db = dbf.newDocumentBuilder();
				Log.d("Service","got a response from server");
				Document doc = db.parse(new InputSource(new StringReader(result)));
				Element docEle=doc.getDocumentElement();
				NodeList nodeList = doc.getElementsByTagName("RefreshResponse");

				if(nodeList != null && nodeList.getLength() > 0) {
					Element el = (Element)nodeList.item(0);
					RspType = el.getFirstChild().getNodeValue();
				}
				NodeList reason=doc.getElementsByTagName("REASON");
				if(reason != null && reason.getLength() > 0) {
					Element el = (Element)reason.item(0);
					Reason = el.getFirstChild().getNodeValue();
				}
				Log.d("service","reason of update is:"+Reason);
				
				Log.d("result is",result);
				if(RspType.equals("NewList"))
				{
					Log.d("Service","response is new updates");
					displayNotificationMessage("New updates Available");
					nodeList=doc.getElementsByTagName("ParkingSpot");
					parking_db.parkingVector = new Vector< ParkingSpotsList>();

					if(nodeList!=null && nodeList.getLength()>0)
					{
						for(int i = 0 ; i < nodeList.getLength();i++)
						{
							Element el = (Element)nodeList.item(i);
							longitude=getDoubleValue(el,"Longitud_A");
							latitude= getDoubleValue(el,"Latitud_A");
							Coordinate a=new Coordinate(longitude,latitude);
							longitude=getDoubleValue(el,"Longitud_B");
							latitude= getDoubleValue(el,"Latitud_B");					
							Coordinate b=new Coordinate(longitude,latitude);
							ParkingSpot ps=new ParkingSpot(a,b);
							ps.spotId=getIntegerValue(el,"SpotID");
							String status=getTextValue(el,"status");
							if(status.equals("AVAILABLE"))
								ps.parkingStatus=0;
							else if(status.equals("NOTAVAILABLE"))
								ps.parkingStatus=1;
							else
								ps.parkingStatus=2;
							ps.accuracyLevel=getIntegerValue(el,"accuracyLevel");
							ps.street=getTextValue(el,"street");
							ps.side=getTextValue(el,"side");
							ps.cellID= getIntegerValue(el,"CellID");
							ps.timeToAvailable=getTextValue(el,"timeToAvailable");
							ps.gridID=getIntegerValue(el,"gridID");
							ps.street=getTextValue(el,"street");
							ps.side=getTextValue(el,"side");
							
						//	if((ps.spotId>28)&&(ps.spotId<40))
							//	Log.d("id status",Integer.toString(ps.spotId)+" "+Integer.toString(ps.parkingStatus));
							addToVector(ps);
					


						}
						Log.d("Service","vector is full- turn off service!!!!");
						LocationViewers.mapView.postInvalidate();
						RefreshService.this.stopSelf();
						
						
					}					
				}
				else if(RspType.equals("NoNeed"))
				{
					displayNotificationMessage("No updates Available");
					Log.d("Service","no updates available");
					RefreshService.this.stopSelf();
				}
				else{
					//Toast.makeText( getApplicationContext(),result,Toast.LENGTH_LONG).show();
					Log.d("Service Response","Service Response is not correct" +result);
				}

			} catch (MalformedURLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ParserConfigurationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (SAXException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}


		} 
	};

	
	public IBinder onBind(Intent arg0) {
		Log.d("Service","onBind");
		
		return null;
	}
	public void onCreate() {
		Log.d("Service","onCreate");
		notificationMgr =(NotificationManager)getSystemService(
				NOTIFICATION_SERVICE);
		parking_db=ParkingDB.getInstance();
		displayNotificationMessage("starting Background Service");
	}
	public void onDestroy() {
		// TODO Auto-generated method stub
		Log.d("Service","onDestroy");
		runningFlag=false;
		super.onDestroy();
		//displayNotificationMessage("Background Service was auto destroyed");
	}
	@Override
	public void onStart(Intent intent, int startId) {
		// TODO Auto-generated method stub
		Log.d("Service","onStart");
		super.onStart(intent, startId);
		if(runningFlag==false)
		{
			runningFlag = true;
			//displayNotificationMessage("performing request");
			Thread thr = new Thread(null, new ServiceWorker(), "BackgroundService");
			thr.start();
		}
	
	}
	@Override
	public boolean onUnbind(Intent intent) {
		// TODO Auto-generated method stub
		Log.d("Service","onUnbind");
		//Toast.makeText(this, "MyAlarmService.onUnbind()", Toast.LENGTH_LONG).show();
		return super.onUnbind(intent);
	}
	
	private void displayNotificationMessage(String message)
	{
		Notification notification = new Notification(R.drawable.notification,
				message,System.currentTimeMillis());
		PendingIntent contentIntent =
			PendingIntent.getActivity(this, 0,new Intent(this, DrawIcons.class), 0);
		notification.setLatestEventInfo(this, "Background Service",message,
				contentIntent);
		notificationMgr.notify(R.string.app_notification_id, notification);
	}
	class ServiceWorker implements Runnable
	{
		final ResponseHandler<String> responseHandler = new ResponseHandler<String>() {   
			public String handleResponse(HttpResponse response) {    
				//StatusLine status = response.getStatusLine();        
				HttpEntity entity = response.getEntity();          
				String result = null; 
				try { 
					result = inputStreamToString(entity.getContent());   
					Message message = new Message();     
					Bundle bundle = new Bundle();         
					bundle.putString("RESPONSE", result); 
					message.setData(bundle); 
					handler.sendMessage(message);         
				} catch (IOException e) { 
					Log.e("Class6",  " ", e); 
				} 
				return result; 
			} 
		}; 
		public void run() {
			if (runningFlag){

				Log.d(RefreshService.TAG, "service processing");
				HttpClient httpclient = new DefaultHttpClient();
				parking_db=ParkingDB.getInstance();
				Log.d("service","open screen");
				HttpPost httppost = new HttpPost("http://"+parking_db.instanceDNS+":8080/ParkApp/DataUpdate");

				try {
					try{
						DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();

						DocumentBuilder docBuilder = builderFactory.newDocumentBuilder();

						//creating a new instance of a DOM to build a DOM tree.
						Document doc = docBuilder.newDocument();
						Element Request = doc.createElement("MSG_TYPE");
						Request.appendChild(doc.createTextNode("DATA_REFRESH"));
						doc.appendChild(Request);
						
						Element Userid=doc.createElement("USER_ID");
						SharedPreferences ref= getSharedPreferences("com.ruthy.parkApp",MODE_PRIVATE);
						int id=Integer.parseInt(ref.getString("my_id", "0"));
						Userid.appendChild(doc.createTextNode(Integer.toString(id)));//can be 0 on newUser!!
						Request.appendChild(Userid);
						
						
						
						Element longi=doc.createElement("LONGI");
						Element lati=doc.createElement("LAT");
						if(parking_db.gps==true)
						{
							Log.d("DrawIcons","gps is true");
							longi.appendChild(doc.createTextNode(Double.toString(parking_db.curLoc.latitude)));
							lati.appendChild(doc.createTextNode(Double.toString(parking_db.curLoc.longitude)));
						}
						else
						{
							longi.appendChild(doc.createTextNode("34.76519264280796"));//change to user location
							lati.appendChild(doc.createTextNode("32.068188492013135"));//change to user location
						}
			
						Userid.appendChild(longi);
						longi.appendChild(lati);

						TransformerFactory factory = TransformerFactory.newInstance();
						Transformer transformer = factory.newTransformer();

						transformer.setOutputProperty(OutputKeys.INDENT, "yes");

						StringWriter sw = new StringWriter();
						StreamResult result = new StreamResult(sw);
						DOMSource source = new DOMSource(doc);
						transformer.transform(source, result);
						String xmlString = sw.toString();
						//Log.d("xmlString","^^^^^^"+xmlString);


						StringEntity se = new StringEntity(xmlString); //XML as a string
						se.setContentType("text/xml"); //declare it as XML
						httppost.setEntity(se);

						String response = httpclient.execute(httppost,responseHandler);
						Log.d("Service","Response* "+response);
					}
					catch (ClientProtocolException e) {
						Log.e("LOGTAG", " " , e); 
					} catch (IOException e) {
						Log.e("LOGTAG", " " , e); 
					}

				}
				catch(Exception e)
				{
					Log.e("LOGTAG", " " , e); 
				}
			}
			// do background processing here...
			// stop the service when done...
			// BackgroundService.this.stopSelf();
		}
	}
	
	private String getTextValue(Element ele, String tagName) {
		String textVal = null;
		NodeList nl = ele.getElementsByTagName(tagName);
		if(nl != null && nl.getLength() > 0) {
			Element el = (Element)nl.item(0);
			textVal = el.getFirstChild().getNodeValue();
		}

		return textVal;
	}
	
	void addToVector(ParkingSpot ps)
	{
		int i;

		for( i=0;i<parking_db.parkingVector.size();i++)
		{
			if((parking_db.parkingVector.get(i).list.get(0).street.equals(ps.street))&&(parking_db.parkingVector.get(i).list.get(0).side.equals(ps.side)))
			{
				parking_db.parkingVector.get(i).list.add(ps);
				break;
			}	
		}
		if(i==parking_db.parkingVector.size())
		{
			parking_db.parkingVector.add(new ParkingSpotsList());
			parking_db.parkingVector.elementAt(parking_db.parkingVector.size()-1).list.add(ps);

		}

	}

	private double getDoubleValue(Element ele, String tagName) {
		String strVal = null;
		double doubleVal=0;
		NodeList nl = ele.getElementsByTagName(tagName);
		if(nl != null && nl.getLength() > 0) {
			Element el = (Element)nl.item(0);
			strVal = el.getFirstChild().getNodeValue();
			doubleVal=Double.parseDouble(strVal);
		}

		return doubleVal;
	}

	private int getIntegerValue(Element ele, String tagName) {
		String strVal = null;
		int intVal=0;
		NodeList nl = ele.getElementsByTagName(tagName);
		if(nl != null && nl.getLength() > 0) {
			Element el = (Element)nl.item(0);
			strVal = el.getFirstChild().getNodeValue();
			intVal=Integer.parseInt(strVal);
		}

		return intVal;
	}



	
	public static String inputStreamToString(final InputStream stream) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(stream));
		StringBuilder sb = new StringBuilder();
		String line = null;
		while ((line = br.readLine()) != null) {
			sb.append(line + "\n");
		}
		br.close();
		return sb.toString();
	}


	

}
